package com.yinp.proapp.module.game.fourcolormap;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

import androidx.annotation.Nullable;

import com.yinp.proapp.R;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

/**
 * Created by Administrator on 2019-10-21.
 */

public class MapView extends View {
    public MapView(Context context) {
        this(context, null);
    }

    public MapView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MapView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    Context mContext;
    List<ProvinceItem> itemList;//省
    Paint mPaint;
    RectF totalRect;
    private float scale = 1.0f;//中国地图的缩放比例
    private boolean isEnd = false;

    private void init(Context context) {
        mContext = context;
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        itemList = new ArrayList<>();
        mThread.start();
    }

    //确定是需要缩小还是放大，scale存放系数
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //获取当前控件的高度 让地图宽高适配当前控件
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        if (totalRect != null) {
            //当所有的地图Path加载出来以后，requestLayout()会调用方法，就有值了。
            double mapWidth = totalRect.width();
            scale = (float) (width / mapWidth); //获取控件高度为了让地图能缩放到和控件宽高适配
        }
        setMeasuredDimension(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
    }

    /**
     * 加载地图的路径相对比较耗时，这里开启子线程来加载
     */
    private Thread mThread = new Thread() {
        @Override
        public void run() {
            super.run();
            InputStream inputStream = mContext.getResources().openRawResource(R.raw.chinasvg);
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //获取DocumentBuilderFactory实例
            DocumentBuilder builder = null;
            try {
                builder = factory.newDocumentBuilder();
                Document doc = builder.parse(inputStream);//解析svg的输入流
                Element rootElement = doc.getDocumentElement();//该属性允许直接访问文档的文档元素的子节点
                NodeList items = rootElement.getElementsByTagName("path"); //获取地图的整个上下左右位置，
                float left = -1;
                float right = -1;
                float top = -1;
                float bottom = -1;
                List<ProvinceItem> list = new ArrayList<>();//存放解析出来的省
                for (int i = 0; i < items.getLength(); i++) {
                    Element element = (Element) items.item(i);
                    String pathData = element.getAttribute("android:pathData");

                    Path path = PathParser.createPathFromPathData(pathData);//获取每一个path，即要绘画的路径
                    ProvinceItem provinceItem = new ProvinceItem(path);//设置路径,初始化省对象
                    // 取每个省的上下左右 最后拿出最小或者最大的来充当 总地图的上下左右
                    RectF rect = new RectF();
                    provinceItem.provinceRectF = rect;
                    path.computeBounds(rect, false);//获取path的边界值,用于比对和判断选择
                    //获取最小的左和上，最大的右和下确定整个中国地图的矩形,确定地图最大范围
                    left = left == -1 ? rect.left : Math.min(left, rect.left);
                    right = right == -1 ? rect.right : Math.max(right, rect.right);
                    top = top == -1 ? rect.top : Math.min(top, rect.top);
                    bottom = bottom == -1 ? rect.bottom : Math.max(bottom, rect.bottom);

                    list.add(provinceItem);
                }
                itemList = list;
                totalRect = new RectF(left, top, right, bottom);//设置地图的上下左右位置
                // 加载完以后刷新界面,在主线程中就不用Looper.getMainLooper();
                Handler handler = new Handler(Looper.getMainLooper());
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        //requestLayout方法会导致View的onMeasure、onLayout、onDraw方法被调用；
                        // invalidate方法则只会导致View的onDraw方法被调用
                        requestLayout();
                        invalidate();
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    /**
     * 相邻块儿的颜色不能相同
     *
     * @param provinceItem
     * @return false 即是白色或者相邻色不同
     */
    public boolean neighborColor(ProvinceItem provinceItem) {
        if (mColor == Color.WHITE) {
            return false;
        }
        for (int i = 0; i < itemList.size(); i++) {
            if (RectF.intersects(provinceItem.provinceRectF, itemList.get(i).provinceRectF)) {
                if (provinceItem == itemList.get(i)) {
                    continue;
                }
                if (itemList.get(i).selectColor == Color.WHITE) {
                    continue;
                }
                if (itemList.get(i).selectColor == mColor) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 手指触摸的时候触发,因为大小按比例变化，所以点击的点的具体位置也要按比例变化。
     *
     * @param event
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (!isEnd) {
                handleTouch(event.getX() / scale, event.getY() / scale);
            } else {
                Toast.makeText(mContext, "恭喜你，四色地图已经完成", Toast.LENGTH_SHORT).show();
            }
        }
        return super.onTouchEvent(event);
    }

    /**
     * 获取选中的块儿，并判断是否颜色相同
     *
     * @param x
     * @param y
     */
    private void handleTouch(float x, float y) {
        if (itemList == null) {
            return;
        }
        ProvinceItem selectItem = null;
        for (int i = 0; i < itemList.size(); i++) {
            if (itemList.get(i).isContains(x, y)) {
                Log.d("abcd", "handleTouch: " + i);
                if (!FCM_judge.judge(itemList, i, mColor)) {
                    itemList.get(i).selectColor = mColor;
                    postInvalidate();
                } else {
                    Toast.makeText(mContext, "相邻省颜色不能相同", Toast.LENGTH_SHORT).show();
                }
            }
        }
//        for (ProvinceItem provinceItem : itemList) {
//            if (provinceItem.isContains(x, y)) {
//                selectItem = provinceItem;//选中的省
//                //返回true就不能为地图块儿上色
//                if (!neighborColor(selectItem)) {
//                    provinceItem.selectColor = mColor;
//                } else {
//                    Toast.makeText(mContext, "相邻省颜色不能相同", Toast.LENGTH_SHORT).show();
//                }
//            }
//        }
        if (selectItem != null) {
            //刷新调用onDraw
//            postInvalidate();
        }
    }

    /**
     * 判断地图是否填满
     *
     * @return
     */
    public boolean isFull() {
        for (int i = 0; i < itemList.size(); i++) {
            if (i == 11 || i == 19) {
                continue;
            } else {
                if (itemList.get(i).selectColor == Color.WHITE) {
                    return false;
                }
            }
        }
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (itemList != null && !itemList.isEmpty()) {
            canvas.scale(scale, scale);//把画布缩放匹配到本控件的宽高控件有多大，地图就放大或缩小到适应
            for (ProvinceItem provinceItem : itemList) {
                provinceItem.drawItem(canvas, mPaint);
            }
            if (isFull()) {
                //在这里添加游戏结束的处理
                isEnd = true;
                Toast.makeText(mContext, "恭喜你，四色地图已经完成", Toast.LENGTH_SHORT).show();
            }
        }
    }

    int mColor = Color.RED;

    //改变画笔的颜色
    public void setColor(int color) {
        mColor = color;
    }

    public void restart() {
        isEnd = false;
        for (int i = 0; i < itemList.size(); i++) {
            itemList.get(i).selectColor = Color.WHITE;
        }
        postInvalidate();
    }
}
